'''
Created on 09/10/2012

@author: rcasal
'''
from gluon.tools import Auth
from gluon.dal import Field
from gluon.validators import IS_NOT_EMPTY, IS_NOT_IN_DB, IS_EMAIL, IS_IN_DB,\
    CRYPT
from repositories.i_repository import IRepository
from domain.entities.usuario import Usuario, Sector
from gluon.html import URL

class SectorRepository(IRepository):
    '''
    classdocs
    '''

    def __init__(self, sigecon, T):
        '''
        Constructor
        '''
        self.__sigecon = sigecon
        self.__table = None
        self.__T = T
        
    def define_table(self, migrate = False):
        
        self.__sigecon.define_table('Sectores'
        ,Field('descripcion', 'string', length = 250, unique = True, required = True, notnull = True)
        ,Field('admite_derivacion',  type = 'boolean', length = 1, required = True, notnull = True )
        ,migrate = migrate
        )
        self.__table = self.__sigecon['Sectores']
        self.add_requires()
        
    def add_requires(self):
        self.__table.descripcion.requires = [IS_NOT_IN_DB(self.__sigecon, self.__sigecon.Sectores.descripcion), IS_NOT_EMPTY()]
        
    def add_represents(self):
        IRepository.add_represents(self)
            
    def findOne(self, ident):
        sector = None
        fields = self.__sigecon(self.__sigecon.Sectores.id == ident).select().last()
        if fields:
            sector = Sector.deserialize(fields)
        return sector
    
    def findAll(self):
        resultado = self.__sigecon(self.__sigecon.Sectores.id > 0).select()
        sectores = []
        for fields in resultado:
            sectores.append(Sector.deserialize(fields))
        return sectores
    
    def save(self, entity):
        raise NotImplementedError()
    
    def delete(self, entity):
        raise NotImplementedError()
    
class AuthRepository(Auth):
    
    
    def __init__(self, sigecon, T):
        '''
        Constructor
        '''
        Auth.__init__(self, sigecon)
        self.__T = T
        self.settings.actions_disabled=['register',
                                        'change_password',
                                        'request_reset_password',
                                        'profile',
                                        'retrieve_username',
                                        'retrieve_password']
        self.settings.login_after_registration = False
        self.settings.registration_requires_verification = False
        self.settings.registration_requires_approval = False
        self.settings.reset_password_requires_verification = False
        self.settings.on_failed_authorization = URL(c = 'errors',f='not_authorized')
    
        self.__table = None
        self.__sigecon = sigecon
        
        
    def define_tables(self, migrate=False):
        
        self.__sigecon.define_table(
        self.settings.table_user_name,
        Field('first_name', length=128, default='', required = True, notnull= True, label = 'Nombre'),
        Field('last_name', length=128, default='', required = True, notnull= True, label = 'Apellido'),
        Field('email', length=128, default='', unique=True, required = True, notnull= True, label = 'Email'),
        Field('username', length=50, default='', unique=True, required = True, notnull= True, label = 'Usuario'),
        Field('password', 'password', length=512, readable=False, required = True, notnull= True, label='Clave'),
        Field('registration_key', length=512, writable=False, required = True, notnull= True, readable=False, default=''),
        Field('reset_password_key', length=512, writable=False, required = True, notnull= True, readable=False, default=''),
        Field('sector', 'reference Sectores', required = True, notnull= True, label = 'Sector'),
        migrate = migrate
        )
        
        Auth.define_tables(self, username=True, migrate=migrate)
        self.__table = self.__sigecon[self.settings.table_user_name]
        self.add_requires()
        self.add_represents()
        
    def add_requires(self):
        self.__table.first_name.requires = IS_NOT_EMPTY()
        self.__table.last_name.requires = IS_NOT_EMPTY()
        self.__table.password.requires = [IS_NOT_EMPTY(),CRYPT()]
        self.__table.username.requires = IS_NOT_IN_DB(self.__sigecon, self.settings.table_user.username)
        self.__table.email.requires = [IS_EMAIL(), IS_NOT_IN_DB(self.__sigecon, self.settings.table_user.email)]    
        self.__table.sector.requires = IS_IN_DB(self.__sigecon, self.__sigecon.Sectores.id,'%(descripcion)s')    
        
    def add_represents(self):
        table_user = self.__table
        table_auth_membership = self.__sigecon['auth_membership']
        table_auth_group = self.__sigecon['auth_group']
        
        table_user.sector.represent = lambda ident: self.__sigecon.Sectores(ident).descripcion if ident > 0 else "sin datos"
        table_auth_membership.user_id.represent = lambda ident: table_user(ident).username if ident > 0 else "sin datos"
        table_auth_membership.group_id.represent = lambda ident: table_auth_group(ident).role if ident > 0 else "sin datos"

        
    def get_user(self):
        return self.userById(self.user_id)
    
    def userById(self, ident):
        user = None
        res = self.__sigecon(self.__sigecon[self.settings.table_user_name].id == ident).select().last()
        
        if res:
            user = Usuario()
            user.ID = res.id
            user.nombre = res.first_name
            user.apellido = res.last_name
            user.mail = res.email
            user.username = res.username
            user.password = res.password
            user.sector.ID = res.sector
            #user.grupos = .... lalala
        return user

    def findAllUsers(self, asdict = False):
        usuarios = self.__sigecon(self.__sigecon[self.settings.table_user_name].id > 0).select()
        if asdict == True:
            return usuarios
        raise NotImplementedError()
    
    def get_table_user(self):
        return self.__table
    
    def get_user_groups(self):
        raise NotImplementedError()
    
    def save_user(self, fields):
        return self.__table.insert(**self.__table._filter_fields(fields))
    
        